home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / das / direct.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  10KB  |  559 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  DIRECT.C
  9.  *
  10.  *  Directives
  11.  *
  12.  */
  13.  
  14. /*
  15. **      $Filename: direct.c $
  16. **      $Author: dice $
  17. **      $Revision: 30.5 $
  18. **      $Date: 1994/06/13 18:41:08 $
  19. **      $Log: direct.c,v $
  20.  * Revision 30.5  1994/06/13  18:41:08  dice
  21.  * byte ordering portability
  22.  * align opcode was broken
  23.  *
  24.  * Revision 30.0  1994/06/10  18:07:43  dice
  25.  * .
  26.  *
  27.  * Revision 1.2  1993/09/19  20:54:09  jtoebes
  28.  * Fixed BUG06033 - DAS does not report original C source line numbers.
  29.  * Handled setting a global variable to the current line being processed.
  30.  *
  31.  * Revision 1.1  1993/09/19  20:19:25  jtoebes
  32.  * Initial revision
  33.  *
  34. **/
  35.  
  36. #include "defs.h"
  37.  
  38. Prototype   MachCtx *ProcCtx;
  39. Prototype   short   MC68020;
  40. Prototype   short   MC68881;
  41. Prototype   long    DebugLineNo;
  42.  
  43. Prototype   void    BadLabel(Label **);
  44. Prototype   void    DeleteTrailingSpaces(char *);
  45. Prototype   void    ExecOpCodeA(MachCtx *);
  46. Prototype   long    ExecOpCodeB(MachCtx *, long);
  47. Prototype   long    ExecOpCodeC(MachCtx *, long);
  48. Prototype   long    ExecOpCodeG(MachCtx *, long);
  49. Prototype   void    SetForcedLinkFlag(void);
  50. Prototype   void    SetSubroutineCallFlag(void);
  51. Prototype   void    SetA5UsedFlag(void);
  52. Prototype   long    GetFlags(void);
  53. Prototype   void    StrToAlign(char *, long *, long *, long);
  54.  
  55. MachCtx *ProcCtx;
  56. short    MC68020;
  57. short    MC68881;
  58. long    DebugLineNo;
  59.  
  60. void
  61. BadLabel(plab)
  62. Label **plab;
  63. {
  64.     *plab = GetLabelByName("____dummy____");
  65.     cerror(EERROR_DIRECTIVE_REQUIRES_LABEL);
  66. }
  67.  
  68. void
  69. DeleteTrailingSpaces(str)
  70. char *str;
  71. {
  72.     char *ptr = str + strlen(str) - 1;
  73.  
  74.     /* if (*str) check avoids bug in GNU-C -O/-O2 options */
  75.  
  76.     if (*str) {
  77.     while (ptr >= str) {
  78.         if (*ptr == ' ' || *ptr == 9) {
  79.         --ptr;
  80.         continue;
  81.         }
  82.         break;
  83.     }
  84.         ++ptr;
  85.         *ptr = 0;
  86.     }
  87. }
  88.  
  89. /*
  90.  *  Pass A
  91.  *
  92.  */
  93.  
  94. void
  95. ExecOpCodeA(mc)
  96. MachCtx *mc;
  97. {
  98.     OpCod *oc = mc->OpCode;
  99.     char *str = mc->m_Operands;
  100.     Label *lab;
  101.  
  102.     DeleteTrailingSpaces(str);
  103.     switch(oc->Id) {
  104.     case OdEQU:
  105.     if ((lab = mc->Label) == NULL) {
  106.         BadLabel(&lab);
  107.     }
  108.     mc->Label = NULL;
  109.     mc->m_XLabel = lab;
  110.     lab->l_Type = LT_INT;
  111.     lab->l_Value = ParseIntExp(str);
  112.     dbprintf(0, ("label %s value %ld\n", lab->Name, lab->l_Value));
  113.     break;
  114.     case OdREG:     /*    RegList */
  115.     if ((lab = mc->Label) == NULL)
  116.         BadLabel(&lab);
  117.     mc->Label = NULL;
  118.     mc->m_XLabel = lab;
  119.     lab->l_Type = LT_REG;
  120.     (void)ParseRegList(str, &lab->l_Mask);
  121.     lab->l_RegNo =    OnlyOneRegister(lab->l_Mask);
  122.     break;
  123.     case OdXREF:
  124.     {
  125.         Label *lab = GetLabelByName(str);
  126.         lab->l_Type = LT_EXT;
  127.         mc->m_XLabel = lab;
  128.     }
  129.     break;
  130.     case OdXDEF:
  131.     {
  132.         Label *lab = GetLabelByName(str);
  133.         mc->m_XLabel = lab;
  134.         /* label added to xdef list in passB */
  135.     }
  136.     break;
  137.     case OdDS:
  138.     /*
  139.      *  handle COMMON DS statements
  140.      */
  141.  
  142.     if (mc->Sect && mc->Sect->Type == SECT_COMMON) {
  143.         long value;
  144.  
  145.         if ((value = ParseIntExp(str)) != 0) {
  146.         if ((lab = mc->Label) != NULL) {
  147.             mc->Label = NULL;
  148.             mc->m_XLabel = lab;
  149.             lab->l_Type = LT_EXT;
  150.             lab->l_Value = ParseIntExp(str);
  151.             dbprintf(0, ("common label %s value %ld\n", lab->Name, lab->l_Value));
  152.         } else {
  153.             BadLabel(&lab);
  154.         }
  155.         }
  156.     }
  157.     case OdDC:
  158.     mc->m_SaveStr = str;
  159.     break;
  160.     case OdALIGN:
  161.     mc->m_SaveStr = str;
  162.     break;
  163.     case OdSECTION:
  164.     NewSection(str);
  165.     mc->Sect = CurSection;
  166.     break;
  167.     case OdEND:
  168.     break;
  169.     case OdPROCSTART:
  170.     if (*str)
  171.         Optimize = atoi(str);
  172.     else if (Optimize == 0)
  173.         Optimize = 1;
  174.     ProcCtx = mc;
  175.     break;
  176.     case OdPROCEND:
  177.     if (*str)
  178.         SetForcedLinkFlag();
  179.     ProcCtx = NULL;
  180.     break;
  181.     case OdMC68020:
  182.     MC68020 = 1;
  183.     break;
  184.     case OdMC68881:
  185.     MC68881 = 1;
  186.     break;
  187.     case OdDEBUG:
  188.     DebugLineNo = strtol(str, NULL, 0);
  189.         mc->m_DebugLine = DebugLineNo;
  190.     break;
  191.     default:
  192.     cerror(ESOFT_BAD_DIRECTIVE);
  193.     }
  194. }
  195.  
  196. /*
  197.  *  In pass B add XDEFd labels to the appropriate section list
  198.  *
  199.  *  m_Operands now invalid, contains m_Addr instead
  200.  *
  201.  */
  202.  
  203. long
  204. ExecOpCodeB(mc, addr)
  205. MachCtx *mc;
  206. long addr;
  207. {
  208.     switch(mc->OpCode->Id) {
  209.     case OdXDEF:
  210.     {
  211.         Label *lab;
  212.         if ((lab = mc->m_XLabel) && lab->XDefLink == (void *)-1L)
  213.         {
  214.             if (lab->Sect == NULL)
  215.             {
  216.                 lab->Sect = CurSection;
  217.                 cerror(EERROR_UNDEFINED_LABEL, lab->Name);
  218.             }
  219.         lab->XDefLink = lab->Sect->XDefLab;
  220.         lab->Sect->XDefLab = lab;
  221.         }
  222.     }
  223.     break;
  224.     case OdSECTION:
  225.     CurSection->Addr = addr;
  226.     CurSection = mc->Sect;
  227.     addr = CurSection->Addr;
  228.     break;
  229.     case OdDS:
  230.         {
  231.         long t;
  232.  
  233.         if (mc->OpSize == 0)
  234.         cerror(EERROR_DIRECT_REQUIRES_SIZE);
  235.         t = ParseIntExp(mc->m_SaveStr) * mc->OpSize;
  236.         if (t == 0)                /*  align. XXX align always? */
  237.         t = Align(addr, mc->OpSize) - addr;
  238.         mc->Bytes = t;
  239.         addr += mc->Bytes;
  240.     }
  241.     break;
  242.     case OdALIGN:
  243.     {
  244.         long align = 1;
  245.         long alignVal = 0;
  246.  
  247.         if (mc->OpSize == 0)
  248.         cerror(EERROR_DIRECT_REQUIRES_SIZE);
  249.         StrToAlign(mc->m_SaveStr, &align, &alignVal, mc->OpSize);
  250.  
  251.         mc->Bytes = Align(addr, align * mc->OpSize) - addr;
  252.         addr += mc->Bytes;
  253.     }
  254.     break;
  255.     case OdDC:
  256.     /*
  257.      *  Save expression string but count elements.
  258.      */
  259.     {
  260.         char *str = mc->m_SaveStr;
  261.         long t;
  262.  
  263.         t = 0;
  264.  
  265.         if (*str)
  266.         ++t;
  267.         while (*str) {
  268.         if (*str == '\'') {     /*  HACK XXX    */
  269.             for (++str; *str && *str != '\''; ++str)
  270.             ++t;
  271.             if (*str == '\'')
  272.             ++str;
  273.             --t;
  274.         }
  275.         if (*str == ',')
  276.             ++t;
  277.         ++str;
  278.         }
  279.         mc->Bytes = (mc->OpSize == 0) ? t : (t * mc->OpSize);
  280.     }
  281.     addr += mc->Bytes;
  282.     break;
  283.     case OdPROCSTART:
  284.     ProcCtx = mc;
  285.     break;
  286.     case OdPROCEND:
  287.     ProcCtx = NULL;
  288.     break;
  289.     case OdMC68020:
  290.     MC68020 = 1;
  291.     break;
  292.     case OdMC68881:
  293.     MC68881 = 1;
  294.     break;
  295.     case OdDEBUG:
  296.         DebugLineNo = mc->m_DebugLine;
  297.     break;
  298.     default:
  299.     break;
  300.     }
  301.     return(addr);
  302. }
  303.  
  304. void
  305. SetForcedLinkFlag()
  306. {
  307.     if (ProcCtx)
  308.     ProcCtx->Bytes |= MF_FORCELINK;
  309. }
  310.  
  311. void
  312. SetSubroutineCallFlag()
  313. {
  314.     if (ProcCtx)
  315.     ProcCtx->Bytes |= MF_CALLMADE;
  316. }
  317.  
  318. void
  319. SetA5UsedFlag()
  320. {
  321.     if (ProcCtx)
  322.     ProcCtx->Bytes |= MF_A5USED;
  323. }
  324.  
  325. long
  326. GetFlags()
  327. {
  328.     if (ProcCtx)
  329.     return(ProcCtx->Bytes);
  330.     return(MF_CALLMADE|MF_A5USED);
  331. }
  332.  
  333. long
  334. ExecOpCodeC(mc, addr)
  335. MachCtx *mc;
  336. long addr;
  337. {
  338.     switch(mc->OpCode->Id) {
  339.     case OdSECTION:
  340.     CurSection->Addr = addr;
  341.     CurSection = mc->Sect;
  342.     addr = CurSection->Addr;
  343.     break;
  344.     case OdDS:
  345.     addr += mc->Bytes;
  346.     break;
  347.     case OdALIGN:
  348.     {
  349.         long align = 1;
  350.         long alignVal = 0;
  351.  
  352.         StrToAlign(mc->m_SaveStr, &align, &alignVal, mc->OpSize);
  353.  
  354.         mc->Bytes = Align(addr, align) - addr;
  355.         addr += mc->Bytes;
  356.     }
  357.     break;
  358.     case OdDC:
  359.     addr += mc->Bytes;
  360.     break;
  361.     case OdPROCSTART:
  362.     ProcCtx = mc;
  363.     break;
  364.     case OdPROCEND:
  365.     ProcCtx = NULL;
  366.     break;
  367.     case OdMC68020:
  368.     MC68020 = 1;
  369.     break;
  370.     case OdMC68881:
  371.     MC68881 = 1;
  372.     break;
  373.     case OdDEBUG:
  374.     ++CurSection->DebugLen;
  375.     DebugLineNo = mc->m_DebugLine;
  376.     break;
  377.     default:
  378.     break;
  379.     }
  380.     return(addr);
  381. }
  382.  
  383.  
  384. long
  385. ExecOpCodeG(mc, addr)
  386. MachCtx *mc;
  387. long addr;
  388. {
  389.     switch(mc->OpCode->Id) {
  390.     case OdSECTION:
  391.     CurSection->Addr = addr;
  392.     CurSection = mc->Sect;
  393.     addr = CurSection->Addr;
  394.     break;
  395.     case OdDS:
  396.     if (mc->Bytes)
  397.         DumpSectionData(mc->Sect, NULL, mc->Bytes);
  398.     addr += mc->Bytes;
  399.     break;
  400.   case OdALIGN:
  401.     {
  402.         long align = 1;
  403.         long alignVal = 0;
  404.         long i;
  405.         char v_char;
  406.         short v_short;
  407.         long v_long;
  408.  
  409.         StrToAlign(mc->m_SaveStr, &align, &alignVal, mc->OpSize);
  410.  
  411.         v_char = alignVal;
  412.         v_short = ToMsbOrderShort(alignVal);
  413.         v_long = ToMsbOrder(alignVal);
  414.  
  415.         for (i = 0; i < mc->Bytes; i += mc->OpSize) {
  416.         switch(mc->OpSize) {
  417.         case 1:
  418.             {
  419.             DumpSectionData(mc->Sect, &v_char, 1);
  420.             }
  421.             break;
  422.         case 2:
  423.             {
  424.             DumpSectionData(mc->Sect, &v_short, 2);
  425.             }
  426.             break;
  427.         case 4:
  428.             {
  429.             DumpSectionData(mc->Sect, &v_long, 4);
  430.             }
  431.             break;
  432.         }
  433.         }
  434.     }
  435.     addr += mc->Bytes;
  436.     break;
  437.     case OdDC:
  438.     /*
  439.      *  Parse m_SaveStr.
  440.      */
  441.     {
  442.         EffAddr ea;
  443.         char *str = mc->m_SaveStr;
  444.         long bytes = 0;    /*  bytes double check & offset track */
  445.         short hacksq = 0;    /*  hack-in-single-quote          */
  446.  
  447.         while (*str) {
  448.         setmem(&ea, sizeof(ea), 0);
  449.  
  450.         if (hacksq) {
  451.             ea.Offset1 = *str;
  452.             ++str;
  453.             if (*str == '\'') {
  454.             hacksq = 0;
  455.             ++str;
  456.             }
  457.         } else if (*str == '\'') {
  458.             hacksq = 1;
  459.             ++str;
  460.             continue;
  461.         } else
  462.             str = ParseExp(str, &ea.Label1, &ea.Offset1);
  463.  
  464.         /*
  465.          *  ignore .W (which DC1 will generate)
  466.          */
  467.  
  468.         if (*str == '.' && (str[1] == 'w' || str[1] == 'W'))
  469.             str += 2;
  470.  
  471.         /*
  472.          *  XXX allow exp(pc)
  473.          *  XXX allow exp(An)    (data rel)
  474.          */
  475.  
  476.         if (ea.Label1) {
  477.             if (ea.Label1->l_Type == LT_LOC)
  478.             ea.Offset1 += ea.Label1->l_Offset;
  479.             HandleInstReloc(mc->Sect, ea.Label1, addr + bytes, mc->OpSize, ((mc->OpSize == 2) ? RELOC_PCREL : 0));
  480.         }
  481.  
  482.         switch(mc->OpSize) {
  483.         case 0:
  484.             cerror(EERROR_DIRECT_REQUIRES_SIZE);
  485.             break;
  486.         case 1:
  487.             {
  488.             char c = ea.Offset1;
  489.             DumpSectionData(mc->Sect, &c, 1);
  490.             }
  491.             break;
  492.         case 2:
  493.             {
  494.             short c = ToMsbOrderShort(ea.Offset1);
  495.             DumpSectionData(mc->Sect, &c, 2);
  496.             }
  497.             break;
  498.         case 4:
  499.             {
  500.             long c = ToMsbOrder(ea.Offset1);
  501.             DumpSectionData(mc->Sect, &c, 4);
  502.             }
  503.             break;
  504.         }
  505.         if (hacksq == 0 && *str) {
  506.             if (*str != ',')
  507.             cerror(EERROR_EXPECTED_GOT, *str, *str);
  508.             ++str;
  509.         }
  510.         bytes += mc->OpSize;
  511.         }
  512.         if (bytes != mc->Bytes)
  513.         cerror(ESOFTWARN_DIRECT_BYTES_MISMATCH, mc->Bytes, bytes);
  514.     }
  515.     addr += mc->Bytes;
  516.     break;
  517.     case OdDEBUG:
  518.     {
  519.         Sect *sect = CurSection;
  520.  
  521.         if (sect->DebugAry == NULL)
  522.         sect->DebugAry = zalloc(sizeof(DebugNode) * sect->DebugLen);
  523.         if (sect->DebugIdx >= sect->DebugLen)
  524.         cerror(ESOFT_DEBUG_INTERNAL_ERROR);
  525.         sect->DebugAry[sect->DebugIdx].db_Line = mc->m_DebugLine;
  526.         sect->DebugAry[sect->DebugIdx].db_Offset = addr;
  527.         ++sect->DebugIdx;
  528.     }
  529.     DebugLineNo = mc->m_DebugLine;
  530.     break;
  531.     default:
  532.     break;
  533.     }
  534.     return(addr);
  535. }
  536.  
  537.  
  538. void
  539. StrToAlign(str, palign, pvalue, size)
  540. char *str;
  541. long *palign;
  542. long *pvalue;
  543. long size;
  544. {
  545.     EffAddr ea;
  546.  
  547.     setmem(&ea, sizeof(ea), 0);
  548.  
  549.     str = ParseExp(str, &ea.Label1, &ea.Offset1);
  550.     *palign = ea.Offset1 * size;
  551.  
  552.     if (*str == ',') {
  553.     ParseExp(str + 1, &ea.Label1, &ea.Offset1);
  554.     *pvalue = ea.Offset1;
  555.     }
  556. }
  557.  
  558.  
  559.